package com.tea.room.service.wechat.impl;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tea.room.dao.UserInfoDao;
import com.tea.room.dao.WeChatTokenDao;
import com.tea.room.dao.tea.TeaOrderDao;
import com.tea.room.dao.tea.TeahouseDao;
import com.tea.room.model.Return;
import com.tea.room.model.UserInfo;
import com.tea.room.model.WeChatToken;
import com.tea.room.model.tea.TeaOrder;
import com.tea.room.model.tea.Teahouse;
import com.tea.room.model.xmlBean.Message;
import com.tea.room.model.xmlBean.Xml2Map;
import com.tea.room.service.wechat.WeChatService;
import com.tea.room.util.ConfigUtil;
import com.tea.room.util.ConstantUtil;
import com.tea.room.util.JsonUtil;
import com.tea.room.util.wechat.VerifyTokenUtil;
import com.tea.room.util.wechat.encodingAESKey.WXBizMsgCrypt;

@Service
@Transactional
public class WeChatServiceImpl implements WeChatService {

    private static Logger logger = LoggerFactory.getLogger(WeChatServiceImpl.class);
    private static Properties pro = ConfigUtil.getProperties("wechat.properties");

    @Autowired
    private WeChatTokenDao weChatTokenDao;

    @Autowired
    private TeahouseDao teahouseDao;
    
    @Autowired
    private UserInfoDao userInfoDao;
    
    @Autowired
    private TeaOrderDao teaOrderDao;

    // 认证token
    private String token = pro.getProperty("TOKEN");
    // 消息加解密密钥
    private String encodingAesKey = pro.getProperty("ENCODINGAESKEY");
    // 微信支付分配的公众账号ID
    private String appId = pro.getProperty("APPID");
    // 微信支付分配的公众账号ID
    private String appsecret = pro.getProperty("APPSECRET");

    @Override
    public Boolean verifyToken(HttpServletRequest request) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        logger.info("Token认证传入参数   =signature:" + signature + " =timestamp:" + timestamp + " =nonce:" + nonce);
        boolean flag = false;
        try {
            flag = VerifyTokenUtil.verifyUrl(signature, timestamp, nonce);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("密钥验证状态：" + flag);
        return flag;
    }

    @Override
    public String messageHandle(HttpServletRequest request) {
        String str = "";
        try {
            Map<String, String> map = Xml2Map.xmlToMap(request);
            logger.info("传入参数 :" + map.toString());
            // 明文回复
            // String msgType = map.get("MsgType");
            // if(ConstantUtil.MESSAGE_TEXT.equals(msgType)){
            // str = textMessageHandle(map);
            // }
            // 加密回复
            str = textMessageHandle(request, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("返回参数 :" + str);
        return str;
    }

    /**
     * 文本消息回复（明文回复） @Title: textMessageHandle @param: @param request @return:
     * String @throws
     */
    public String textMessageHandle(Map<String, String> map) {
        Message msg = new Message();
        msg.setToUserName(map.get("FromUserName"));// 消息回复，发送消息人变成接收消息人
        msg.setFromUserName(map.get("ToUserName"));// 消息回复，接收消息人变成发送消息人
        msg.setCreateTime(map.get("CreateTime"));// 时间戳
        msg.setMsgType(map.get("MsgType"));// 消息类型
        String content = map.get("Content");// 回复内容
        msg.setContent(content);
        String xml = Xml2Map.beanToXml(msg);
        return xml;
    }

    /**
     * @throws Exception
     *             文本消息回复 密文回复
     * @Title: textMessageHandle
     * @param: @param
     *             request
     * @return: String
     */
    public String textMessageHandle(HttpServletRequest request, Map<String, String> map) throws Exception {
        String msg_signature = request.getParameter("msg_signature");
        String timestamp = request.getParameter("timestamp");// 时间戳
        String nonce = request.getParameter("nonce");// 随机数
        logger.info("URL传入参数   =signature:" + msg_signature + " =timestamp:" + timestamp + " =nonce:" + nonce);

        // 公众平台发送消息解密
        String format = "<xml><ToUserName><![CDATA[%1$s]]></ToUserName><Encrypt><![CDATA[%2$s]]></Encrypt></xml>";
        String fromXML = String.format(format, map.get("ToUserName"), map.get("Encrypt"));
        WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
        String xmlStr = pc.decryptMsg(msg_signature, timestamp, nonce, fromXML);
        logger.info("公众平台发送消息解密后明文: " + xmlStr);
        Map<String, String> doc = Xml2Map.xmlToMap(xmlStr);

        String content = doc.get("Content");// 用户发送的消息内容
        String type = doc.get("MsgType");// 发送的消息类型
        String user = doc.get("FromUserName");// 发送消息微信ID
        String handle = "";// 回复公众平台内容
        // 根据收到消息内容，进行业务处理
        if (ConstantUtil.MESSAGE_TEXT.equals(type)) {
            String text = message_text(content, user);
            doc.put("Content", text);
        } else if (ConstantUtil.MESSAGE_EVNET.equals(type)) {
            String event = doc.get("Event");
            String eventKey = doc.get("EventKey");
            if (ConstantUtil.MESSAGE_CLICK.equals(event)) {
                doc.put("MsgType", ConstantUtil.MESSAGE_TEXT);
                if (eventKey.equals("V001_GOOD")) {// 获取门锁秘钥
                    doc.put("Content", "门锁秘钥");
                } else if (eventKey.equals("V002_GOOD")) {// 查询订单
                    doc.put("Content", "查询订单");
                } else if (eventKey.equals("V003_GOOD")) {// 操作指南
                    doc.put("Content", "操作指南");
                }
            }
            if (ConstantUtil.MESSAGE_SUBSCRIBE.equals(event)) {
                doc.put("MsgType", ConstantUtil.MESSAGE_TEXT);
                StringBuffer sb = new StringBuffer();
                sb.append("欢迎您关注“倒茶” \n");
                sb.append("倒茶，懂茶更懂你 \n");
                sb.append("茶室预约点击：“预约茶室” \n");
                sb.append("全国咨询热线：13813900552 \n");
                doc.put("Content", sb.toString());
            }
            if (ConstantUtil.MESSAGE_UNSUBSCRIBE.equals(event)) {
                doc.put("MsgType", ConstantUtil.MESSAGE_TEXT);
                StringBuffer sb = new StringBuffer();
                sb.append("欢迎您关注“倒茶” \n");
                sb.append("倒茶，懂茶更懂你 \n");
                sb.append("茶室预约点击：“预约茶室” \n");
                sb.append("全国咨询热线：13813900552 \n");
                doc.put("Content", sb.toString());
            }
        }
        handle = textMessageHandle(doc);// 获取回复明文xml字符串
        logger.info("回复公众平台加密前: " + handle);
        String mingwen = pc.encryptMsg(handle, timestamp, nonce);
        logger.info("回复公众平台加密后: " + mingwen);
        return mingwen;
    }

    @Override
    public void insertAccessToken(WeChatToken wc) {
        weChatTokenDao.updateWCToken(wc);
        weChatTokenDao.insert(wc);
    }

    /**
     * 回复文本消息
     * @param content
     * @param openId
     * @return
     */
    public String message_text(String content, String openId){
        String password = "";
        String txt = content.replaceAll(" ", "");
        String code = "";
        //获取美团订单号
        for(int i=0; i < txt.length(); i++){
            if(txt.charAt(i)>=48 && txt.charAt(i)<=57){
                code += txt.charAt(i);
            }
        }
        //查询订单密码
        TeaOrder order = new TeaOrder();
        order.setOpenId(code);
        List<TeaOrder> list = teaOrderDao.queryOrderByOpenid(order);
        if(list.size()>0){
            password = list.get(0).getPassword();
        }else{
            String msg = "未查询到订单，请确认输入内容！";
            return msg;
        }
        //更新openid
        TeaOrder tea = new TeaOrder();
        tea.setSerno(list.get(0).getSerno());
        tea.setOpenId(openId);
        teaOrderDao.updateOpenId(tea);
        String msg = "亲，您的密码已经生成，请唤醒门锁键盘之后，输入密码(" + password + ")按#号确认开门";
        return msg;
    }

    @Override
    public String messageNotice(TeaOrder o) {
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, Object> content = new HashMap<String, Object>();
        map.put("touser", "o6BSO5hLYw1eZbbmk-YLOszZhkg8");
        map.put("msgtype", "text");
        content.put("content", "阿姨，茶室预定还有10分钟结束！请稍后去打扫!");
        map.put("text", content);
        // 组装模板消息数据
        logger.info("参数："+JsonUtil.mapToJsonObject(map).toJSONString());
        // 获取token拼接请求链接
        WeChatToken token = weChatTokenDao.queryWCToken();
        String url = pro.getProperty("CUSTOM_MESG") + token.getAccess_token();
        com.tea.room.util.HttpClient client = com.tea.room.util.HttpClient.getInstance();
        // 请求接口
        client.sendHttpPost(url, JsonUtil.mapToJsonObject(map).toString(), "application/json");
        return null;
    }

    @Override
    public String startNotice(TeaOrder o) {
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String, Object> first = new HashMap<String, Object>();
        Map<String, Object> keyword1 = new HashMap<String, Object>();
        Map<String, Object> keyword2 = new HashMap<String, Object>();
        Map<String, Object> keyword3 = new HashMap<String, Object>();
        Map<String, Object> keyword4 = new HashMap<String, Object>();
        Map<String, Object> remark = new HashMap<String, Object>();
        Teahouse teahouse = new Teahouse();
        teahouse.setTeaCode(o.getTeaCode());
        Teahouse query = teahouseDao.query(teahouse);
        
        // 组装模板消息数据
        first.put("color", "#000000");//字体颜色
        first.put("value", "茶室据预定开始时间只剩10分钟啦！");
        data.put("first", first);

        keyword1.put("color", "#173177");//字体颜色
        keyword1.put("value", "共享茶室");//服务项目
        data.put("keyword1", keyword1);

        keyword2.put("color", "#173177");//字体颜色
        keyword2.put("value", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(o.getStart()));//服务时间
        data.put("keyword2", keyword2);
        
        keyword3.put("color", "#173177");//字体颜色
        keyword3.put("value", query.getAdderss());//店面地址
        data.put("keyword3", keyword3);
        
        keyword4.put("color", "#173177");//字体颜色
        keyword4.put("value", query.getPhone());//联系电话
        data.put("keyword4", keyword4);

        remark.put("color", "#000000");//字体颜色
        remark.put("value", "");
        data.put("remark", remark);
        map.put("touser", o.getOpenId());//用户id
        map.put("template_id", "NCWQzkT8I7vflIeSAmsZHWUX5bRx5FniCZcDxO8HQoY");//模板ID
        map.put("url", "");//点击模版消息跳转的地址
        map.put("data", data);
        System.out.println(map);
        // 获取token拼接请求链接
        WeChatToken token = weChatTokenDao.queryWCToken();
        String url = pro.getProperty("SEND_MESG") + token.getAccess_token();
        com.tea.room.util.HttpClient client = com.tea.room.util.HttpClient.getInstance();
        // 请求接口
        client.sendHttpPost(url, JsonUtil.mapToJsonObject(map).toString(), "application/json");
        return null;
    }

    @Override
    public Return addUserInfo(String openid) {
        Return rn = new Return();
        rn.setIsSuccessflag(true);
        UserInfo user = new UserInfo();
        try {
            WeChatToken token = weChatTokenDao.queryWCToken();
            String url = pro.getProperty("USERINFO");
            com.tea.room.util.HttpClient client = com.tea.room.util.HttpClient.getInstance();
            String get = client.sendHttpGet(url+ "?access_token=" + token.getAccess_token() + "&openid=" + openid + "&lang=zh_CN");
            System.out.println(get);
            Map<String, Object> map = JsonUtil.jsonToMap(get);
            user.setSubscribe(map.get("subscribe").toString());
            user.setOpenid(openid);
            user.setNickname(map.get("nickname").toString());
            user.setSex(map.get("sex").toString());
            user.setCity(map.get("city").toString());
            user.setProvince(map.get("province").toString());
            user.setCountry(map.get("country").toString());
            user.setLanguage(map.get("language").toString());
            user.setHeadimgurl(map.get("headimgurl").toString());
            user.setSubscribe_scene(map.get("subscribe_scene").toString());
            user.setSubscribe_time(map.get("subscribe_time").toString());
            UserInfo info = userInfoDao.query(user);
            rn.setDataMap(map);
            if(info == null){
                userInfoDao.insert(user);  
            } else {
                userInfoDao.update(user);
            }
        } catch (Exception e) {
            rn.setIsSuccessflag(false);
            e.printStackTrace();
        }
        return rn;
    }

    @Override
    public UserInfo queryUserInfo(String openid) {
        UserInfo user = new UserInfo();
        user.setOpenid(openid);
        UserInfo info = userInfoDao.query(user);
        return info;
    }
    
    
    public static void main(String[] args) {
//        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=21_OGf3bybIKHEVWrDCa8bsoOU1B1KfGonXezQhH9QQXtpv5WFDMX6Kp5cr_PvdmsEH5DeyLIdeoveLNdGK4LWl9bGRv8rU85xslTVomVJUd_Jw7t3s84IWZbjjXV7zeBrdI60d9SI_G9RrxqwSDYKfADAPKW&type=jsapi";
//        com.tea.room.util.HttpClient client = com.tea.room.util.HttpClient.getInstance();
//        String get = client.sendHttpGet(url);
//        System.out.println(get);
        String content = "sds123sfddgr疏忽456    \n十五万大是大非7890";
        String txt = content.replaceAll(" ", "");
        String code = "";
        for(int i=0; i < txt.length(); i++){
            if(txt.charAt(i)>=48 && txt.charAt(i)<=57){
                code += txt.charAt(i);
            }
        }
        System.out.println(code);
    }

	@Override
	public Return queryOpenid(String code) {
		Return rn = new Return();
		String format = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1$s&secret=%2$s&code=%3$s&grant_type=authorization_code";
		String url = String.format(format, appId, appsecret, code);
		System.out.println("url" + url);
        com.tea.room.util.HttpClient client = com.tea.room.util.HttpClient.getInstance();
        String get = client.sendHttpGet(url);
        Map<String, Object> map = JsonUtil.jsonToMap(get);
        rn.setDataMap(map);
		return rn;
	}
	
}
